package com.zp.business.impl.hospitalizationNotice;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.zp.business.api.diagnosis.HisDiagnosis;
import com.zp.business.api.diagnosis.HisDiagnosisVo;
import com.zp.business.entity.hospitalizationNotice.HospitalizationNotice;
import com.zp.business.entity.hospitalizationNotice.bo.HospitalizationNoticeBo;
import com.zp.business.entity.hospitalizationNotice.vo.HospitalizationNoticeVo;
import com.zp.business.entity.patient.vo.ClinicMasterVo;
import com.zp.business.mapper.diagnosis.HisDiagnosisMapper;
import com.zp.business.mapper.hospitalizationNotice.HospitalizationNoticeMapper;
import com.zp.business.mapper.patient.ClinicMasterMapper;
import com.zp.business.service.hospitalizationNotice.IHospitalizationNoticeService;
import com.zp.common.core.constant.BaseConstants;
import com.zp.common.core.constant.CacheNames;
import com.zp.common.core.constant.UserConstants;
import com.zp.common.core.utils.DateUtils;
import com.zp.common.core.utils.StringUtils;
import com.zp.common.myBatis.core.page.PageQuery;
import com.zp.common.myBatis.core.page.TableDataInfo;
import com.zp.common.redis.utils.CacheUtils;
import com.zp.system.api.entity.SysDept;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 住院通知单Service业务层处理
 *
 * @author zhang peng
 * @ date 2024-06-26
 */
@RequiredArgsConstructor
@Service
public class HospitalizationNoticeServiceImpl implements IHospitalizationNoticeService {

    static Map<String, SysDept> SYS_DEPT_MAP = CacheUtils.get(CacheNames.SYS_DEPT);
    private final HospitalizationNoticeMapper baseMapper;
    private final ClinicMasterMapper clinicMasterMapper;
    private final HisDiagnosisMapper diagnosisMapper;

    /**
     * 查询住院通知单
     */
    @Override
    public HospitalizationNoticeVo queryById(String noticeId) {
        return baseMapper.selectVoById(noticeId);
    }

    /**
     * 查询住院通知单列表(分页)
     */
    @Override
    public TableDataInfo<HospitalizationNoticeVo> queryPageList(HospitalizationNoticeBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<HospitalizationNotice> lqw = buildQueryWrapper(bo);
        Page<HospitalizationNoticeVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        result.getRecords().forEach(item->{
            item.setDeptAdmissionToName(ObjectUtils.isNotEmpty(SYS_DEPT_MAP) && StringUtils.isNotBlank(item.getDeptAdmissionTo()) ?
                    SYS_DEPT_MAP.get(item.getDeptAdmissionTo()).getDeptName() : "");
            item.setWardAdmissionToName(ObjectUtils.isNotEmpty(SYS_DEPT_MAP) && StringUtils.isNotBlank(item.getWardAdmissionTo()) ?
                    SYS_DEPT_MAP.get(item.getWardAdmissionTo()).getDeptName() : "");
        });
        return TableDataInfo.build(result);
    }

    /**
     * 查询住院通知单列表(不分页)
     */
    @Override
    public List<HospitalizationNoticeVo> queryList(HospitalizationNoticeBo bo) {
        LambdaQueryWrapper<HospitalizationNotice> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<HospitalizationNotice> buildQueryWrapper(HospitalizationNoticeBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<HospitalizationNotice> lqw = Wrappers.lambdaQuery();
        lqw.eq(StringUtils.isNotBlank(bo.getClinicId()), HospitalizationNotice::getClinicId, bo.getClinicId());
        lqw.like(StringUtils.isNotBlank(bo.getName()), HospitalizationNotice::getName, bo.getName());
        lqw.eq(StringUtils.isNotBlank(bo.getInputCode()), HospitalizationNotice::getInputCode, bo.getInputCode());
        lqw.eq(StringUtils.isNotBlank(bo.getSex()), HospitalizationNotice::getSex, bo.getSex());
        lqw.eq(StringUtils.isNotBlank(bo.getAge()), HospitalizationNotice::getAge, bo.getAge());
        lqw.eq(bo.getAgeMonth() != null, HospitalizationNotice::getAgeMonth, bo.getAgeMonth());
        lqw.eq(bo.getAgeDay() != null, HospitalizationNotice::getAgeDay, bo.getAgeDay());
        lqw.eq(bo.getAgeHours() != null, HospitalizationNotice::getAgeHours, bo.getAgeHours());
        lqw.eq(bo.getAgeMinutes() != null, HospitalizationNotice::getAgeMinutes, bo.getAgeMinutes());
        lqw.eq(StringUtils.isNotBlank(bo.getNation()), HospitalizationNotice::getNation, bo.getNation());
        lqw.eq(StringUtils.isNotBlank(bo.getNationality()), HospitalizationNotice::getNationality, bo.getNationality());
        lqw.eq(StringUtils.isNotBlank(bo.getMarriage()), HospitalizationNotice::getMarriage, bo.getMarriage());
        lqw.eq(StringUtils.isNotBlank(bo.getOccupation()), HospitalizationNotice::getOccupation, bo.getOccupation());
        lqw.eq(StringUtils.isNotBlank(bo.getBedNum()), HospitalizationNotice::getBedNum, bo.getBedNum());
        lqw.eq(bo.getBirthdayDate() != null, HospitalizationNotice::getBirthdayDate, bo.getBirthdayDate());
        lqw.eq(StringUtils.isNotBlank(bo.getNativePlace()), HospitalizationNotice::getNativePlace, bo.getNativePlace());
        lqw.eq(StringUtils.isNotBlank(bo.getNativePlaceCode()), HospitalizationNotice::getNativePlaceCode, bo.getNativePlaceCode());
        lqw.eq(StringUtils.isNotBlank(bo.getZipCode()), HospitalizationNotice::getZipCode, bo.getZipCode());
        lqw.eq(StringUtils.isNotBlank(bo.getHomePlace()), HospitalizationNotice::getHomePlace, bo.getHomePlace());
        lqw.eq(StringUtils.isNotBlank(bo.getHomePlaceCode()), HospitalizationNotice::getHomePlaceCode, bo.getHomePlaceCode());
        lqw.eq(StringUtils.isNotBlank(bo.getAddress()), HospitalizationNotice::getAddress, bo.getAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getAddressCode()), HospitalizationNotice::getAddressCode, bo.getAddressCode());
        lqw.eq(StringUtils.isNotBlank(bo.getIdentity()), HospitalizationNotice::getIdentity, bo.getIdentity());
        lqw.eq(StringUtils.isNotBlank(bo.getInFlag()), HospitalizationNotice::getInFlag, bo.getInFlag());
        lqw.eq(StringUtils.isNotBlank(bo.getIdNo()), HospitalizationNotice::getIdNo, bo.getIdNo());
        lqw.eq(StringUtils.isNotBlank(bo.getPhone()), HospitalizationNotice::getPhone, bo.getPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getContacts()), HospitalizationNotice::getContacts, bo.getContacts());
        lqw.eq(StringUtils.isNotBlank(bo.getContactsRelation()), HospitalizationNotice::getContactsRelation, bo.getContactsRelation());
        lqw.eq(StringUtils.isNotBlank(bo.getContactsNation()), HospitalizationNotice::getContactsNation, bo.getContactsNation());
        lqw.eq(StringUtils.isNotBlank(bo.getContactsIdentity()), HospitalizationNotice::getContactsIdentity, bo.getContactsIdentity());
        lqw.eq(StringUtils.isNotBlank(bo.getContactsAddressCode()), HospitalizationNotice::getContactsAddressCode, bo.getContactsAddressCode());
        lqw.eq(StringUtils.isNotBlank(bo.getContactsAddress()), HospitalizationNotice::getContactsAddress, bo.getContactsAddress());
        lqw.eq(StringUtils.isNotBlank(bo.getContactsPhone()), HospitalizationNotice::getContactsPhone, bo.getContactsPhone());
        lqw.eq(StringUtils.isNotBlank(bo.getUnitInContract()), HospitalizationNotice::getUnitInContract, bo.getUnitInContract());
        lqw.eq(StringUtils.isNotBlank(bo.getChargeType()), HospitalizationNotice::getChargeType, bo.getChargeType());
        lqw.eq(StringUtils.isNotBlank(bo.getDeptAdmissionTo()), HospitalizationNotice::getDeptAdmissionTo, bo.getDeptAdmissionTo());
        lqw.eq(StringUtils.isNotBlank(bo.getWardAdmissionTo()), HospitalizationNotice::getWardAdmissionTo, bo.getWardAdmissionTo());
        lqw.eq(bo.getAdmissionTime() != null, HospitalizationNotice::getAdmissionTime, bo.getAdmissionTime());
        lqw.eq(StringUtils.isNotBlank(bo.getAcceptingMoney()), HospitalizationNotice::getAcceptingMoney, bo.getAcceptingMoney());
        lqw.eq(bo.getAttackdate() != null, HospitalizationNotice::getAttackdate, bo.getAttackdate());
        lqw.eq(StringUtils.isNotBlank(bo.getHospitalSituation()), HospitalizationNotice::getHospitalSituation, bo.getHospitalSituation());
        lqw.eq(StringUtils.isNotBlank(bo.getQuarantine()), HospitalizationNotice::getQuarantine, bo.getQuarantine());
        lqw.eq(StringUtils.isNotBlank(bo.getDiagnosis()), HospitalizationNotice::getDiagnosis, bo.getDiagnosis());
        lqw.eq(StringUtils.isNotBlank(bo.getClinicDiagnosis()), HospitalizationNotice::getClinicDiagnosis, bo.getClinicDiagnosis());
        lqw.eq(StringUtils.isNotBlank(bo.getAttention()), HospitalizationNotice::getAttention, bo.getAttention());
        lqw.eq(StringUtils.isNotBlank(bo.getOrgId()), HospitalizationNotice::getOrgId, bo.getOrgId());
        return lqw;
    }

    /**
     * 新增住院通知单
     */
    @Override
    public Boolean insertByBo(HospitalizationNoticeBo bo) {
        bo.setInFlag(BaseConstants.ENTRY_AND_EXIT_HOSPITAL_STATUS.FOUR);
        HospitalizationNotice add = BeanUtil.toBean(bo, HospitalizationNotice.class);
        validEntityBeforeSave(add);
        add.initEntity();
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setNoticeId(add.getNoticeId());
        }
        return flag;
    }

    /**
     * 修改住院通知单
     */
    @Override
    public Boolean updateByBo(HospitalizationNoticeBo bo) {
        HospitalizationNotice update = BeanUtil.toBean(bo, HospitalizationNotice.class);
        update.updateInfo();
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(HospitalizationNotice entity) {
        //TODO 做一些数据校验,如唯一约束
    }

    /**
     * 批量删除住院通知单
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<String> ids, Boolean isValid) {
        if (isValid) {
            //TODO 做一些业务上的校验,判断是否需要校验
        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    /**
     * 询患者入院基本信息如果存在直接插patVisitIndex，不存在查patMasterIndex信息
     *
     * @param bo
     * @return
     */
    @Override
    public HospitalizationNoticeVo getHosPatientInfo(HospitalizationNoticeBo bo) {
        HospitalizationNoticeVo hospitalizationNoticeVo = baseMapper.selectVoOne(Wrappers.<HospitalizationNotice>lambdaQuery()
                .eq(HospitalizationNotice::getClinicId, bo.getClinicId())
//                .eq(HospitalizationNotice::getInFlag, BaseConstants.ENTRY_AND_EXIT_HOSPITAL_STATUS.ONE)
        );
        if (ObjectUtils.isEmpty(hospitalizationNoticeVo)) {
            ClinicMasterVo clinicMasterVo = clinicMasterMapper.selectVoById(bo.getClinicId());
            hospitalizationNoticeVo = BeanUtil.toBean(clinicMasterVo, HospitalizationNoticeVo.class);
            hospitalizationNoticeVo.setClinicId(clinicMasterVo.getId());
            // 获取患者是否为新生儿
            Integer i = DateUtils.twoDateReturnInt(clinicMasterVo.getBirthdayDate(), DateUtils.getNowDate());
            hospitalizationNoticeVo.setNewbornFlag(i <= 30 ? UserConstants.YES : UserConstants.NO);
            // 查询患者门诊诊断信息
            List<HisDiagnosisVo> hisDiagnosisVos = diagnosisMapper.selectVoList(Wrappers.<HisDiagnosis>lambdaQuery()
                    .eq(HisDiagnosis::getClinicId, clinicMasterVo.getId())
                    .eq(HisDiagnosis::getDelFlag, "0")
                    // 诊断类型 5 门诊
                    .eq(HisDiagnosis::getDiagnosisType, "5")
            );
            if (CollectionUtils.isNotEmpty(hisDiagnosisVos)) {
                hospitalizationNoticeVo.setClinicDiagnosis(hisDiagnosisVos.stream()
                        .map(HisDiagnosisVo::getIcdName)
                        .collect(Collectors.joining(";")));
            }
        }
        return hospitalizationNoticeVo;
    }
}
